// admin/system/dao/sys_role_menu_dao.go
package dao

import (
	"go-admin1/admin/system/model"
	"go-admin1/internal/infrastructure/database"
	"go-admin1/internal/infrastructure/logger"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

// SysRoleMenuDao 角色菜单关联数据访问接口
type SysRoleMenuDao interface {
	Create(roleMenu *model.SysRoleMenu) error
	GetByRoleID(roleID int64) ([]*model.SysRoleMenu, error)
	GetByMenuID(menuID int64) ([]*model.SysRoleMenu, error)
	DeleteByRoleID(roleID int64) error
	DeleteByMenuID(menuID int64) error
	DeleteByRoleIDAndMenuID(roleID, menuID int64) error
	ListMenuIDsByRoleID(roleID int64) ([]int64, error)
	ListRoleIDsByMenuID(menuID int64) ([]int64, error)
}

type sysRoleMenuDao struct {
	db *gorm.DB
}

// NewSysRoleMenuDao 创建角色菜单关联数据访问实例
func NewSysRoleMenuDao() SysRoleMenuDao {
	return &sysRoleMenuDao{
		db: database.GetDB(),
	}
}

func (rm *sysRoleMenuDao) Create(roleMenu *model.SysRoleMenu) error {
	logger.Info("创建角色菜单关联",
		zap.Int64("role_id", roleMenu.RoleID),
		zap.Int64("menu_id", roleMenu.MenuID))
	return rm.db.Create(roleMenu).Error
}

func (rm *sysRoleMenuDao) GetByRoleID(roleID int64) ([]*model.SysRoleMenu, error) {
	logger.Debug("根据角色ID获取角色菜单关联", zap.Int64("role_id", roleID))
	var roleMenus []*model.SysRoleMenu
	err := rm.db.Where("role_id = ?", roleID).Find(&roleMenus).Error
	return roleMenus, err
}

func (rm *sysRoleMenuDao) GetByMenuID(menuID int64) ([]*model.SysRoleMenu, error) {
	logger.Debug("根据菜单ID获取角色菜单关联", zap.Int64("menu_id", menuID))
	var roleMenus []*model.SysRoleMenu
	err := rm.db.Where("menu_id = ?", menuID).Find(&roleMenus).Error
	return roleMenus, err
}

func (rm *sysRoleMenuDao) DeleteByRoleID(roleID int64) error {
	logger.Info("根据角色ID删除角色菜单关联", zap.Int64("role_id", roleID))
	return rm.db.Where("role_id = ?", roleID).Delete(&model.SysRoleMenu{}).Error
}

func (rm *sysRoleMenuDao) DeleteByMenuID(menuID int64) error {
	logger.Info("根据菜单ID删除角色菜单关联", zap.Int64("menu_id", menuID))
	return rm.db.Where("menu_id = ?", menuID).Delete(&model.SysRoleMenu{}).Error
}

func (rm *sysRoleMenuDao) DeleteByRoleIDAndMenuID(roleID, menuID int64) error {
	logger.Info("根据角色ID和菜单ID删除角色菜单关联",
		zap.Int64("role_id", roleID),
		zap.Int64("menu_id", menuID))
	return rm.db.Where("role_id = ? AND menu_id = ?", roleID, menuID).Delete(&model.SysRoleMenu{}).Error
}

func (rm *sysRoleMenuDao) ListMenuIDsByRoleID(roleID int64) ([]int64, error) {
	logger.Debug("根据角色ID获取菜单ID列表", zap.Int64("role_id", roleID))
	var menuIDs []int64
	err := rm.db.Model(&model.SysRoleMenu{}).Where("role_id = ?", roleID).Pluck("menu_id", &menuIDs).Error
	return menuIDs, err
}

func (rm *sysRoleMenuDao) ListRoleIDsByMenuID(menuID int64) ([]int64, error) {
	logger.Debug("根据菜单ID获取角色ID列表", zap.Int64("menu_id", menuID))
	var roleIDs []int64
	err := rm.db.Model(&model.SysRoleMenu{}).Where("menu_id = ?", menuID).Pluck("role_id", &roleIDs).Error
	return roleIDs, err
}
